﻿using System;
using System.Linq;
using System.Text;
using EzDesk.Apps.Data.ProjectModule;
using EzDesk.Apps.Model.ProjectModule;
using EzDesk.Core.Model;
using EzDesk.Utility;
using EzDesk.Utility.Extensions;
using EzDesk.Utility.Web.Extensions;

namespace EzDesk.Apps.ServiceImpl.ProjectModule.History
{
    public class ExpiredWorkitemHistoryRecorder: WorkitemHistoryRecorder
    {
        public ExpiredWorkitemHistoryRecorder(Guid workitemId)
            : base(workitemId, null, "ExpiredWorkitemHistory")
        {
        }
        protected override string GetWorkitemContent()
        {
            return "工作任务 \"{0}\" 过期了".FormatString(Workitem.Title);
        }
    }

    public class PostponeWorkitemHistoryRecorder : WorkitemHistoryRecorder
    {
        public PostponeWorkitemHistoryRecorder(Guid workitemId, Guid senderId)
            : base(workitemId, senderId, "PostponeWorkitemHistory")
        {
        }
        protected override string GetWorkitemContent()
        {
            return "{0} 将工作任务 \"{1}\" 延期到了 {2}".FormatString(Sender.Name, Workitem.Title, Workitem.PlanOn.Value.ToFullDate());
        }
    }
    
    public class FinishWorkitemHistoryRecorder: WorkitemHistoryRecorder
    {
        public FinishWorkitemHistoryRecorder(Guid workitemId, Guid? senderId)
            : base(workitemId, senderId, "FinishWorkitemHistory")
        {
        }
        protected override string GetWorkitemContent()
        {
            return "{0} 完成了工作任务 \"{1}\"".FormatString(Sender.Name, Workitem.Title);
        }
    }
    public class RemoveFromProjectWorkitemHistoryRecorder : WorkitemHistoryRecorder
    {
        public RemoveFromProjectWorkitemHistoryRecorder(Guid workitemId, Guid? senderId)
            : base(workitemId, senderId, "RemoveFromProjectWorkitemHistory")
        {
        }
        protected override string GetWorkitemContent()
        {
            return "{0} 将工作任务 \"{1}\" 从项目中移除".FormatString(Sender.Name, Workitem.Title);
        }
    }

    public class ContentUpdatedWokitemHistoryRecorder: WorkitemHistoryRecorder
    {
        protected Workitem OldWorkitem { get; set; }

        public ContentUpdatedWokitemHistoryRecorder(
            Workitem oldWorkitem, Workitem newWorkitem, Guid? senderId)
        {
            OldWorkitem = oldWorkitem;
            innerInitializeWorkitemHistory(
                newWorkitem.ProjectId.HasValue ? newWorkitem : oldWorkitem,
                senderId, 
                "ContentUpdatedWokitemHistory");
        }

        protected override string GetWorkitemContent()
        {
            int rowCount = 0;
            var sb = new StringBuilder();
            sb.AppendLine("{0} 将工作任务 \"{1}\" ".FormatString(Sender.Name, OldWorkitem.Title));

            // 任务更名
            if (OldWorkitem.Title != Workitem.Title)
            {
                sb.AppendLine("更名为 \"{2}\"".FormatString(Sender.Name, OldWorkitem.Title, Workitem.Title));
                rowCount++;
            }
            // 如果原来没有关联到这个项目，那么返回一个关联了新的项目历史
            if (OldWorkitem.ProjectId != Workitem.ProjectId && Workitem.ProjectId.HasValue)
            {
                sb.AppendLine("关联到了项目");
                rowCount++;
            }
            // 如果原来没有关联到这个项目，那么返回一个关联了新的项目历史
            if (OldWorkitem.TaskId == null && Workitem.TaskId.HasValue)
            {
                var linkTask = EzDeskProjectContainer.Go(
                    container => container.TaskSet.FirstOrDefault(p => p.Id == Workitem.TaskId));

                sb.AppendLine("关联了项目计划 \"{0}\"".FormatString(linkTask.Name));
                rowCount++;
            }
            // 如果原来没有关联到这个项目，那么返回一个关联了新的项目历史
            if (OldWorkitem.PlanOn != Workitem.PlanOn && Workitem.PlanOn.HasValue)
            {
                sb.AppendLine("截止时间修改为 {0}".FormatString(Workitem.PlanOn.Value.ToFullDate()));
                rowCount++;
            }
            // 修改了任务描述
            if (OldWorkitem.Description != Workitem.Description)
            {
                sb.AppendLine("描述修改为\"{0}\"".FormatString(Workitem.Description.CutString(20)));
                rowCount++;
            }
            // 修改了任务描述
            if (OldWorkitem.Points != Workitem.Points)
            {
                sb.AppendLine("工作量更改为: {0}".FormatString(Workitem.Points.ToString()));
                rowCount++;
            }
            return rowCount > 1 ? GetMuiltipleLineContent(sb) : sb.ToString();
        }
    }

    public class NewOwnerWorkitemHistoryRecorder : WorkitemHistoryRecorder
    {
        public NewOwnerWorkitemHistoryRecorder(Guid workitemId, Guid? senderId)
            : base(workitemId, senderId, "NewOwnerWorkitemHistory")
        {
        }

        protected override string GetWorkitemContent()
        {
            return "{0} 现在负责工作任务 \"{1}\"".FormatString(Sender.Name, Workitem.Title);
        }
    }

    /// <summary>
    /// 项目中有一个新的Workitem被创建的时候记录的项目历史
    /// </summary>
    public class CreateWorkitemHistoryRecorder: WorkitemHistoryRecorder
    {
        public CreateWorkitemHistoryRecorder(Guid workitemId, Guid? senderId)
            : base(workitemId, senderId, "CreateWorkitemHistory")
        {
        }

        protected override string GetWorkitemContent()
        {
            return "{0} 添加了工作任务 \"{1}\"".FormatString(Sender.Name, Workitem.Title);
        }
    }

    public abstract class WorkitemHistoryRecorder : HistoryRecorderBase
    {
        private ProjectHistory _projectHistory = new ProjectHistory();

        public override ProjectHistory ProjectHistory
        {
            get { return _projectHistory; }
        }

        protected Guid WorkitemId { get; set; }
        protected Workitem Workitem { get; set; }
        protected Guid? SenderId { get; set; }
        protected SimpleUser Sender { get; set; }

        protected WorkitemHistoryRecorder()
        {
        }
        protected WorkitemHistoryRecorder(Guid workitemId, Guid? senderId, string categoryName)
        {
            initializeHistory(workitemId, senderId, categoryName);
        }

        protected void innerInitializeWorkitemHistory(Workitem workitem, Guid? senderId, string categoryName)
        {
            SenderId = senderId;
            Workitem = workitem;

            if (senderId.HasValue)
            {
                Sender = EzApiClient.GetSimpleUserById(SenderId.Value);
            }

            _projectHistory = new ProjectHistory()
            {
                Id = Guid.NewGuid(),
                CreateOn = DateTime.Now,
                HistoryType = HistoryType.Workitem,
                ProjectId = Workitem.ProjectId.Value,
                SenderId = senderId,
                LinkUrl = GetWorkitemLinkUrl(),
                Content = GetWorkitemContent(),
                CategoryName = categoryName,
            };
        }

        protected void initializeHistory(Guid workitemId, Guid? senderId, string categoryName)
        {
            WorkitemId = workitemId;
            var workitem = EzDeskProjectContainer.Go(
                container => container.WorkitemSet.FirstOrDefault(p => p.Id == WorkitemId));
            innerInitializeWorkitemHistory(workitem, senderId, categoryName);
        }

        protected abstract string GetWorkitemContent();

        private string GetWorkitemLinkUrl()
        {
            // todo: 这个workitem有可能会显示不出来的，因为这个workitem并不一定是“自己的”Workitem
            return "/project/projectWorkitem/{0}".FormatString(WorkitemId.ToString());
        }
    }
}